import PyInstaller.__main__
import os
import shutil
from pathlib import Path
from utils.icon_converter import convert_svg_to_ico
from utils.logger import Logger
import json

# 获取日志实例
logger = Logger.get_logger()

def verify_resources():
    """验证资源文件完整性"""
    logger.info("开始验证资源文件...")
    
    # 检查必要的目录
    required_dirs = ['resources', 'resources/icons', 'data', 'logs']
    for dir_path in required_dirs:
        if not os.path.exists(dir_path):
            logger.error(f"缺少必要目录: {dir_path}")
            return False
    
    # 检查必要的图标文件
    required_icons = [
        'app.svg', 'back.svg', 'book.svg', 'bookmark.svg',
        'chat.svg', 'close.svg', 'download.svg', 'edit.svg',
        'logo.svg', 'maximize.svg', 'menu.svg', 'minimize.svg',
        'settings.svg'
    ]
    
    for icon in required_icons:
        icon_path = os.path.join('resources/icons', icon)
        if not os.path.exists(icon_path):
            logger.error(f"缺少图标文件: {icon_path}")
            return False
    
    # 检查配置文件
    if not os.path.exists('settings.json'):
        logger.error("缺少配置文件: settings.json")
        return False
    
    logger.info("资源文件验证完成")
    return True

def build_app():
    try:
        # 设置环境变量
        os.environ['PYTHONIOENCODING'] = 'utf-8'
        
        logger.info("开始打包应用程序")
        
        # 验证资源文件
        if not verify_resources():
            raise Exception("资源文件验证失败")
        
        # 清理之前的构建
        for path in ['build', 'dist']:
            if os.path.exists(path):
                shutil.rmtree(path)
                logger.debug(f"清理目录: {path}")
        
        # 转换图标
        svg_path = 'resources/icons/app.svg'
        ico_path = 'resources/icons/app.ico'
        if not convert_svg_to_ico(svg_path, ico_path):
            logger.warning("图标转换失败，将使用默认图标")
            ico_path = None
        
        # 创建spec文件内容
        spec_content = f'''
# -*- mode: python ; coding: utf-8 -*-

a = Analysis(
    ['main.py'],
    pathex=[],
    binaries=[],
    datas=[
        ('resources', 'resources'),
        ('settings.json', '.'),
        ('data', 'data'),
    ],
    hiddenimports=[
        'PyQt6',
        'PyQt6.QtCore',
        'PyQt6.QtGui',
        'PyQt6.QtWidgets',
        'requests',
        'bs4',
        'openai',
        'aiohttp',
        'asyncio',
    ],
    hookspath=[],
    hooksconfig={{}},
    runtime_hooks=[],
    excludes=[],
    noarchive=False,
)

# 添加所有资源文件
resources = Tree('resources', prefix='resources', excludes=['*.pyc'])
a.datas.extend(resources)

pyz = PYZ(a.pure)

exe = EXE(
    pyz,
    a.scripts,
    [],
    exclude_binaries=True,
    name='MiaoShenAI',
    debug=False,
    bootloader_ignore_signals=False,
    strip=False,
    upx=True,
    console=False,
    disable_windowed_traceback=False,
    argv_emulation=False,
    target_arch=None,
    codesign_identity=None,
    entitlements_file=None,
    {f"icon='{ico_path}'" if ico_path else ''},
)

coll = COLLECT(
    exe,
    a.binaries,
    a.datas,
    strip=False,
    upx=True,
    upx_exclude=[],
    name='MiaoShenAI',
)
'''
        
        # 写入spec文件
        spec_file = 'MiaoShenAI.spec'
        with open(spec_file, 'w', encoding='utf-8') as f:
            f.write(spec_content)
        logger.debug("创建spec文件")
        
        # 使用spec文件打包
        logger.info("开始执行PyInstaller打包")
        PyInstaller.__main__.run([
            spec_file,
            '--clean',
            '--noconfirm'
        ])
        
        # 复制额外文件
        dist_dir = Path('dist/MiaoShenAI')
        
        # 创建必要的目录
        for dir_name in ['data', 'logs']:
            (dist_dir / dir_name).mkdir(exist_ok=True)
            logger.debug(f"创建目录: {dir_name}")
            
            # 确保目录有写入权限
            os.chmod(dist_dir / dir_name, 0o777)
            logger.debug(f"设置目录权限: {dir_name}")
        
        # 复制配置文件
        if os.path.exists('settings.json'):
            shutil.copy2('settings.json', dist_dir / 'settings.json')
            logger.debug("复制配置文件")
        
        # 创建空的书架文件
        bookshelf_file = dist_dir / 'data/bookshelf.json'
        if not bookshelf_file.exists():
            with open(bookshelf_file, 'w', encoding='utf-8') as f:
                json.dump({"books": [], "display_settings": {"card_size": 150}}, f, indent=2)
            logger.debug("创建空的书架文件")
        
        # 复制数据文件
        if os.path.exists('data'):
            for file in os.listdir('data'):
                src = Path('data') / file
                dst = dist_dir / 'data' / file
                if src.is_file():
                    shutil.copy2(src, dst)
                    logger.debug(f"复制数据文件: {file}")
        
        # 确保资源文件存在
        resources_dir = dist_dir / 'resources'
        if not resources_dir.exists():
            shutil.copytree('resources', resources_dir)
            logger.debug("复制资源目录")
        
        logger.info("打包完成！")
        
    except Exception as e:
        logger.error(f"打包失败: {str(e)}", exc_info=True)
        raise

if __name__ == '__main__':
    build_app() 